package org.xyl.service.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.xyl.config.RagConfig;
import org.xyl.dto.DiagnosisRequest;
import org.xyl.dto.DiagnosisResponse;
import org.xyl.model.DeviceStatus;
import org.xyl.model.KnowledgeDocument;
import org.xyl.repository.VectorDbService;
import org.xyl.service.DeviceService;
import org.xyl.service.RagService;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * RAG服务实现
 */
@Service
public class RagServiceImpl implements RagService {
    
    private static final Logger logger = LoggerFactory.getLogger(RagServiceImpl.class);
    
    @Autowired
    private VectorDbService vectorDbService;
    
    @Autowired
    private DeviceService deviceService;
    
    @Autowired
    private RagConfig ragConfig;
    
    private boolean initialized = false;
    private final AtomicInteger documentIdCounter = new AtomicInteger(1);
    
    @Override
    public void initializeKnowledgeBase() {
        if (initialized) {
            logger.info("知识库已经初始化");
            return;
        }
        
        try {
            // 初始化向量数据库
            vectorDbService.initialize();
            
            // 添加示例知识库数据
            List<KnowledgeDocument> sampleDocuments = createSampleKnowledgeBase();
            vectorDbService.storeDocuments(sampleDocuments);
            
            initialized = true;
            logger.info("知识库初始化成功，添加了 {} 个文档", sampleDocuments.size());
        } catch (Exception e) {
            logger.error("知识库初始化失败", e);
            throw new RuntimeException("知识库初始化失败", e);
        }
    }
    
    @Override
    public void addDocuments(List<KnowledgeDocument> documents) {
        if (documents == null || documents.isEmpty()) {
            return;
        }
        
        // 为每个文档生成唯一ID
        for (KnowledgeDocument document : documents) {
            if (document.getId() == null) {
                document.setId("doc-" + documentIdCounter.incrementAndGet());
            }
            if (document.getCreatedAt() == 0) {
                document.setCreatedAt(System.currentTimeMillis());
            }
            document.setUpdatedAt(System.currentTimeMillis());
        }
        
        vectorDbService.storeDocuments(documents);
    }
    
    @Override
    public List<KnowledgeDocument> retrieveKnowledge(String query, Map<String, Object> filters) {
        return vectorDbService.search(query, ragConfig.getSearch().getTopK(), filters);
    }
    
    @Override
    public DiagnosisResponse performDiagnosis(DiagnosisRequest request) {
        logger.info("开始执行诊断: 设备ID={}, 问题描述={}", request.getDeviceId(), request.getIssueDescription());
        
        DiagnosisResponse response = new DiagnosisResponse();
        response.setDeviceId(request.getDeviceId());
        
        try {
            // 1. 获取设备状态
            DeviceStatus deviceStatus = deviceService.getDeviceStatus(request.getDeviceId());
            
            // 2. 获取设备日志
            List<String> deviceLogs = deviceService.getDeviceLogs(request.getDeviceId(), 7);
            
            // 3. 构建检索查询
            String query = buildQuery(request, deviceStatus, deviceLogs);
            Map<String, Object> filters = buildFilters(request, deviceStatus);
            
            // 4. 检索相关知识
            List<KnowledgeDocument> relevantKnowledge = retrieveKnowledge(query, filters);
            
            // 5. 分析诊断结果
            List<DiagnosisResponse.Problem> problems = analyzeProblems(request, deviceStatus, deviceLogs, relevantKnowledge);
            response.setProblems(problems);
            
            // 6. 生成解决方案
            List<DiagnosisResponse.Solution> solutions = generateSolutions(problems, deviceStatus, relevantKnowledge);
            response.setSolutions(solutions);
            
            // 7. 设置置信度和状态
            double confidenceScore = calculateConfidenceScore(problems);
            response.setConfidenceScore(String.format("%.2f%%", confidenceScore * 100));
            response.setStatus("SUCCESS");
            
            logger.info("诊断完成，找到 {} 个问题，置信度: {}", problems.size(), response.getConfidenceScore());
        } catch (Exception e) {
            logger.error("诊断失败", e);
            response.setStatus("ERROR");
            response.setConfidenceScore("0%");
        }
        
        return response;
    }
    
    @Override
    public String generateSolution(String problemCode, String context) {
        logger.info("生成解决方案: 问题代码={}", problemCode);
        
        // 模拟基于问题代码和上下文生成解决方案
        Map<String, String> solutionTemplates = new HashMap<>();
        solutionTemplates.put("BATTERY_LOW", "1. 检查电池电压是否低于3.0V\n2. 如电池电压过低，建议更换电池\n3. 检查设备是否频繁唤醒导致耗电增加\n4. 升级到最新固件版本优化电池管理");
        solutionTemplates.put("SIGNAL_WEAK", "1. 检查设备安装位置的信号强度\n2. 如信号强度低于-105dBm，建议调整安装位置\n3. 检查是否有信号遮挡物\n4. 考虑使用信号增强器或中继器");
        solutionTemplates.put("FIRMWARE_OUTDATED", "1. 执行远程固件升级到最新版本\n2. 升级前备份设备配置\n3. 确保设备电量充足\n4. 升级后验证功能是否正常");
        solutionTemplates.put("DISPLAY_ERROR", "1. 检查屏幕连接是否松动\n2. 尝试重置设备\n3. 检查是否有物理损坏\n4. 如问题持续，可能需要更换屏幕组件");
        solutionTemplates.put("NETWORK_CONNECTION", "1. 检查SIM卡是否正确安装\n2. 验证网络配置是否正确\n3. 重启设备和网络设备\n4. 联系网络运营商确认服务状态");
        
        String template = solutionTemplates.getOrDefault(problemCode, "请联系技术支持获取进一步帮助");
        return template + "\n\n上下文信息: " + context;
    }
    
    // 辅助方法
    private List<KnowledgeDocument> createSampleKnowledgeBase() {
        List<KnowledgeDocument> documents = new ArrayList<>();
        
        // 添加设备问题解决方案文档
        String[] solutions = {
            "ESL-202型号在V1.4固件下存在心跳包发送过频的bug，会导致耗电增加。解决方案：升级至V1.5.1。",
            "当设备信号强度低于-105dBm时，通信成功率会显著下降，建议调整设备安装位置。",
            "电池电压低于3.0V时，设备可能无法正常工作，需要更换电池。",
            "屏幕刷新超时通常是由于网络延迟或信号不稳定导致的，建议检查网络连接。",
            "设备离线超过24小时可能是SIM卡费用到期或基站问题，建议联系运营商。"
        };
        
        String[] documentTypes = {"知识库", "故障排查手册", "设备规格书", "常见问题解答", "技术文档"};
        
        for (int i = 0; i < solutions.length; i++) {
            KnowledgeDocument doc = new KnowledgeDocument();
            doc.setId("doc-" + (i + 1));
            doc.setContent(solutions[i]);
            doc.setSource(documentTypes[i % documentTypes.length]);
            doc.setSourceUrl("https://wiki.example.com/docs/" + (i + 1));
            doc.setDocumentType(documentTypes[i % documentTypes.length]);
            
            Map<String, Object> metadata = new HashMap<>();
            metadata.put("device_type", "ESL-" + (200 + i));
            metadata.put("problem_type", getProblemType(solutions[i]));
            metadata.put("created_at", System.currentTimeMillis());
            
            doc.setMetadata(metadata);
            doc.setCreatedAt(System.currentTimeMillis());
            doc.setUpdatedAt(System.currentTimeMillis());
            
            documents.add(doc);
        }
        
        return documents;
    }
    
    private String getProblemType(String content) {
        if (content.contains("耗电")) return "电池问题";
        if (content.contains("信号")) return "通信问题";
        if (content.contains("电压")) return "电池问题";
        if (content.contains("刷新")) return "显示问题";
        if (content.contains("离线")) return "连接问题";
        return "其他问题";
    }
    
    private String buildQuery(DiagnosisRequest request, DeviceStatus status, List<String> logs) {
        StringBuilder query = new StringBuilder();
        query.append(request.getIssueDescription());
        
        // 添加设备状态信息到查询
        query.append(" 设备状态：电池电压 " + status.getBatteryVoltage() + "V, ");
        query.append("信号强度 " + status.getSignalStrength() + "dBm, ");
        query.append("固件版本 " + status.getFirmwareVersion());
        
        // 添加最新日志信息
        if (!logs.isEmpty()) {
            int logCount = Math.min(3, logs.size());
            query.append(" 最近日志：" + String.join(", ", logs.subList(logs.size() - logCount, logs.size())));
        }
        
        return query.toString();
    }
    
    private Map<String, Object> buildFilters(DiagnosisRequest request, DeviceStatus status) {
        Map<String, Object> filters = new HashMap<>();
        filters.put("device_type", status.getDeviceType());
        
        // 根据问题描述添加过滤条件
        String description = request.getIssueDescription().toLowerCase();
        if (description.contains("电池") || description.contains("耗电")) {
            filters.put("problem_type", "电池问题");
        } else if (description.contains("信号") || description.contains("网络")) {
            filters.put("problem_type", "通信问题");
        } else if (description.contains("屏幕") || description.contains("显示")) {
            filters.put("problem_type", "显示问题");
        }
        
        return filters;
    }
    
    private List<DiagnosisResponse.Problem> analyzeProblems(DiagnosisRequest request, DeviceStatus status, 
                                                           List<String> logs, List<KnowledgeDocument> knowledge) {
        List<DiagnosisResponse.Problem> problems = new ArrayList<>();
        
        // 基于设备状态分析问题
        if (status.getBatteryVoltage() < 3.0) {
            DiagnosisResponse.Problem problem = new DiagnosisResponse.Problem();
            problem.setProblemCode("BATTERY_LOW");
            problem.setProblemDescription("电池电压偏低");
            problem.setSeverity("高");
            problem.setConfidence(0.85);
            problems.add(problem);
        }
        
        if (status.getSignalStrength() < -105) {
            DiagnosisResponse.Problem problem = new DiagnosisResponse.Problem();
            problem.setProblemCode("SIGNAL_WEAK");
            problem.setProblemDescription("信号强度弱");
            problem.setSeverity("中");
            problem.setConfidence(0.75);
            problems.add(problem);
        }
        
        // 检查是否有包含错误的日志
        boolean hasErrorLogs = logs.stream().anyMatch(log -> log.contains("ERROR"));
        if (hasErrorLogs) {
            DiagnosisResponse.Problem problem = new DiagnosisResponse.Problem();
            problem.setProblemCode("SYSTEM_ERROR");
            problem.setProblemDescription("系统错误日志");
            problem.setSeverity("中");
            problem.setConfidence(0.65);
            problems.add(problem);
        }
        
        // 如果没有检测到问题，基于知识库分析
        if (problems.isEmpty() && !knowledge.isEmpty()) {
            DiagnosisResponse.Problem problem = new DiagnosisResponse.Problem();
            problem.setProblemCode("KNOWLEDGE_MATCH");
            problem.setProblemDescription("知识库匹配问题");
            problem.setSeverity("低");
            problem.setConfidence(0.5);
            problems.add(problem);
        }
        
        // 按置信度排序
        problems.sort((a, b) -> Double.compare(b.getConfidence(), a.getConfidence()));
        
        return problems;
    }
    
    private List<DiagnosisResponse.Solution> generateSolutions(List<DiagnosisResponse.Problem> problems, 
                                                              DeviceStatus status, 
                                                              List<KnowledgeDocument> knowledge) {
        List<DiagnosisResponse.Solution> solutions = new ArrayList<>();
        
        for (int i = 0; i < problems.size(); i++) {
            DiagnosisResponse.Problem problem = problems.get(i);
            DiagnosisResponse.Solution solution = new DiagnosisResponse.Solution();
            solution.setSolutionId("sol-" + problem.getProblemCode() + "-" + i);
            
            String context = "设备型号: " + status.getDeviceType() + ", 固件版本: " + status.getFirmwareVersion();
            solution.setSteps(generateSolution(problem.getProblemCode(), context));
            
            // 设置解决方案描述
            switch (problem.getProblemCode()) {
                case "BATTERY_LOW":
                    solution.setDescription("电池电压偏低解决方案");
                    break;
                case "SIGNAL_WEAK":
                    solution.setDescription("信号强度弱解决方案");
                    break;
                case "SYSTEM_ERROR":
                    solution.setDescription("系统错误处理方案");
                    break;
                default:
                    solution.setDescription("基于知识库的解决方案");
                    break;
            }
            
            // 设置来源
            solution.setSource("价签系统知识库");
            solution.setSourceUrl("https://wiki.example.com/solutions/" + problem.getProblemCode());
            
            solutions.add(solution);
        }
        
        return solutions;
    }
    
    private double calculateConfidenceScore(List<DiagnosisResponse.Problem> problems) {
        if (problems.isEmpty()) {
            return 0.0;
        }
        
        // 计算平均置信度
        double avgConfidence = problems.stream()
                .mapToDouble(DiagnosisResponse.Problem::getConfidence)
                .average()
                .orElse(0.0);
        
        return avgConfidence;
    }
}